/*******************************************************************************
 * Copyright (c) Jonathan Buck - jonbuck16@gmail.com
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    jonbuck16@gmail.com - initial API and implementation
 *******************************************************************************/
package net.jonbuck.tassoo.ui.preference;

import net.jonbuck.tassoo.ui.nl.Messages;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

/**
 * 
 * 
 * @since 1.0.0
 */
public class GeneralSettingsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {

	private Text widthText;

	private Text heightText;

	private Button btnAutomaticallyReopenThe;

	private Button btnMaximizeTheApplication;

	private Label lblWidth;

	private Label lblHeight;

	private Rectangle displayBounds;

	private Group grpRunning;

	private Text txtAutoSaveValue;

	private Label lblEvery;

	private Label lblMinutes;

	private Button btnMinimizeTheApplication;

	private Button btnAutomaticallySaveThe;

	private Button btnPromptToSave;

	private IPreferencesService preferenceService;

	/**
	 * <p>
	 * <b>Default Constructor</b>
	 * </p>
	 */
	public GeneralSettingsPreferencePage() {
		super();
	}

	/**
	 * 
	 */
	public void init(IWorkbench workbench) {
		this.setDescription(Messages.generalsettingspreferencepage_description);
		this.noDefaultAndApplyButton();
		preferenceService = Platform.getPreferencesService();
		displayBounds = Display.getDefault().getBounds();
	}

	/**
	 * 
	 */
	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		GridLayout gl_container = new GridLayout(1, false);
		gl_container.marginRight = 5;
		gl_container.marginWidth = 0;
		container.setLayout(gl_container);

		Group grpLaunching = new Group(container, SWT.NONE);
		grpLaunching.setLayout(new GridLayout(1, false));
		grpLaunching.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		grpLaunching.setText("Startup");

		btnAutomaticallyReopenThe = new Button(grpLaunching, SWT.CHECK);
		GridData gd_btnAutomaticallyReopenThe = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_btnAutomaticallyReopenThe.horizontalIndent = 5;
		btnAutomaticallyReopenThe.setLayoutData(gd_btnAutomaticallyReopenThe);
		btnAutomaticallyReopenThe.setText("Automatically re-open the last task store on application launch");
		btnAutomaticallyReopenThe.setSelection(preferenceService.getBoolean("net.jonbuck.tassoo", "automatic.task.store.open",
				false, null));

		btnMaximizeTheApplication = new Button(grpLaunching, SWT.CHECK);
		btnMaximizeTheApplication.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (btnMaximizeTheApplication.getSelection()) {
					lblWidth.setEnabled(false);
					widthText.setEnabled(false);
					lblHeight.setEnabled(false);
					heightText.setEnabled(false);
				} else {
					lblWidth.setEnabled(true);
					widthText.setEnabled(true);
					lblHeight.setEnabled(true);
					heightText.setEnabled(true);
				}
			}
		});
		GridData gd_btnMaximizeTheApplication = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
		gd_btnMaximizeTheApplication.horizontalIndent = 5;
		btnMaximizeTheApplication.setLayoutData(gd_btnMaximizeTheApplication);
		btnMaximizeTheApplication.setText("Maximize the application window to the size of the desktop");
		btnMaximizeTheApplication.setSelection(preferenceService.getBoolean("net.jonbuck.tassoo", "maximize.window", false, null));

		Composite windowSizeComposite = new Composite(grpLaunching, SWT.NONE);
		GridData gd_windowSizeComposite = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_windowSizeComposite.horizontalIndent = 5;
		windowSizeComposite.setLayoutData(gd_windowSizeComposite);
		GridLayout gl_windowSizeComposite = new GridLayout(4, false);
		gl_windowSizeComposite.marginLeft = 40;
		windowSizeComposite.setLayout(gl_windowSizeComposite);

		lblWidth = new Label(windowSizeComposite, SWT.NONE);
		lblWidth.setText("Width:");
		lblWidth.setEnabled(!preferenceService.getBoolean("net.jonbuck.tassoo", "maximize.window", false, null));

		widthText = new Text(windowSizeComposite, SWT.BORDER);
		widthText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				validateWidthHeight();
			}
		});
		GridData gd_widthText = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_widthText.widthHint = 60;
		widthText.setLayoutData(gd_widthText);
		widthText.setText(String.valueOf(preferenceService.getInt("net.jonbuck.tassoo", "window.default.width", 1024, null)));
		widthText.setEnabled(!preferenceService.getBoolean("net.jonbuck.tassoo", "maximize.window", false, null));

		lblHeight = new Label(windowSizeComposite, SWT.NONE);
		lblHeight.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblHeight.setText("Height:");
		lblHeight.setEnabled(!preferenceService.getBoolean("net.jonbuck.tassoo", "maximize.window", false, null));

		heightText = new Text(windowSizeComposite, SWT.BORDER);
		heightText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				validateWidthHeight();
			}
		});
		GridData gd_text_1 = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_text_1.widthHint = 60;
		heightText.setLayoutData(gd_text_1);
		heightText.setText(String.valueOf(preferenceService.getInt("net.jonbuck.tasooo", "window.default.height", 768, null)));
		heightText.setEnabled(!preferenceService.getBoolean("net.jonbuck.tassoo", "maximize.window", false, null));

		grpRunning = new Group(container, SWT.NONE);
		grpRunning.setLayout(new GridLayout(1, false));
		grpRunning.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		grpRunning.setText("Running");

		btnMinimizeTheApplication = new Button(grpRunning, SWT.CHECK);
		GridData gd_btnMinimizeTheApplication = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_btnMinimizeTheApplication.horizontalIndent = 5;
		btnMinimizeTheApplication.setLayoutData(gd_btnMinimizeTheApplication);
		btnMinimizeTheApplication.setText("Minimize the application to the system tray");
		btnMinimizeTheApplication.setSelection(preferenceService.getBoolean("net.jonbuck.tassoo",
				"minimize.application.system.tray", true, null));

		btnAutomaticallySaveThe = new Button(grpRunning, SWT.CHECK);
		btnAutomaticallySaveThe.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (btnAutomaticallySaveThe.getSelection()) {
					lblEvery.setEnabled(true);
					txtAutoSaveValue.setEnabled(true);
					lblMinutes.setEnabled(true);
				} else {
					lblEvery.setEnabled(false);
					txtAutoSaveValue.setEnabled(false);
					lblMinutes.setEnabled(false);
				}
			}
		});
		GridData gd_btnAutomaticallySaveThe = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_btnAutomaticallySaveThe.horizontalIndent = 5;
		btnAutomaticallySaveThe.setLayoutData(gd_btnAutomaticallySaveThe);
		btnAutomaticallySaveThe.setText("Automatically Save the currently open Task Store");
		btnAutomaticallySaveThe.setSelection(preferenceService.getBoolean("net.jonbuck.tassoo",
				"automatically.save.task.store.when.running", false, null));

		Composite autoSaveOptionsComposite = new Composite(grpRunning, SWT.NONE);
		GridData gd_autoSaveOptionsComposite = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_autoSaveOptionsComposite.horizontalIndent = 5;
		autoSaveOptionsComposite.setLayoutData(gd_autoSaveOptionsComposite);
		GridLayout gl_autoSaveOptionsComposite = new GridLayout(3, false);
		gl_autoSaveOptionsComposite.marginLeft = 40;
		autoSaveOptionsComposite.setLayout(gl_autoSaveOptionsComposite);

		lblEvery = new Label(autoSaveOptionsComposite, SWT.NONE);
		lblEvery.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblEvery.setText("Every:");
		lblEvery.setEnabled(preferenceService.getBoolean("net.jonbuck.tassoo", "automatically.save.task.store.when.running", false,
				null));

		txtAutoSaveValue = new Text(autoSaveOptionsComposite, SWT.BORDER);
		GridData gd_txtAutoSaveValue = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_txtAutoSaveValue.widthHint = 60;
		txtAutoSaveValue.setLayoutData(gd_txtAutoSaveValue);
		txtAutoSaveValue.setText(preferenceService.getString("net.jonbuck.tassoo", "automatically.save.minutes", "5", null));
		txtAutoSaveValue.setEnabled(preferenceService.getBoolean("net.jonbuck.tassoo",
				"automatically.save.task.store.when.running", false, null));

		lblMinutes = new Label(autoSaveOptionsComposite, SWT.NONE);
		lblMinutes.setText("Minutes");
		lblMinutes.setEnabled(preferenceService.getBoolean("net.jonbuck.tassoo", "automatically.save.task.store.when.running",
				false, null));

		Group grpShutdown = new Group(container, SWT.NONE);
		grpShutdown.setLayout(new GridLayout(1, false));
		grpShutdown.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		grpShutdown.setText("Shutdown");

		btnPromptToSave = new Button(grpShutdown, SWT.CHECK);
		GridData gd_btnPromptToSave = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_btnPromptToSave.horizontalIndent = 5;
		btnPromptToSave.setLayoutData(gd_btnPromptToSave);
		btnPromptToSave.setText("Prompt to save the currently open task store");
		btnPromptToSave.setSelection(preferenceService.getBoolean("net.jonbuck.tassoo", "prompt.to.save.task.store.on.exit", false,
				null));

		return container;
	}

	/**
	 * 
	 */
	private void validateWidthHeight() {
		if (widthText != null && heightText != null) {
			if (StringUtils.isNotBlank(widthText.getText()) && StringUtils.isNotBlank(heightText.getText())) {
				if (Integer.parseInt(widthText.getText()) > displayBounds.width
						| Integer.parseInt(heightText.getText()) > displayBounds.height) {
					setErrorMessage("The specified screen dimensions are greater than the current resolution allows");
					setValid(false);
				} else {
					setErrorMessage(null);
					setValid(true);
				}
			} else {
				setErrorMessage("Width and Height must be specified");
				setValid(false);
			}
		}
	}

	/**
	 * 
	 */
	public boolean performOk() {
		Preferences tassooNode = preferenceService.getRootNode().node(ConfigurationScope.SCOPE).node("net.jonbuck.tassoo");
		tassooNode.putBoolean("automatic.task.store.open", btnAutomaticallyReopenThe.getSelection());
		tassooNode.putBoolean("maximize.window", btnMaximizeTheApplication.getSelection());
		tassooNode.put("window.default.width", widthText.getText());
		tassooNode.put("window.default.height", heightText.getText());
		tassooNode.putBoolean("minimize.application.system.tray", btnMinimizeTheApplication.getSelection());
		tassooNode.putBoolean("automatically.save.task.store.when.running", btnAutomaticallySaveThe.getSelection());
		tassooNode.put("automatically.save.minutes", txtAutoSaveValue.getText());
		tassooNode.putBoolean("prompt.to.save.task.store.on.exit", btnPromptToSave.getSelection());
		try {
			preferenceService.getRootNode().flush();
		} catch (BackingStoreException e) {
			// TODO Handle backing store exception properly
			e.printStackTrace();
		}
		return super.performOk();
	}
}
